﻿package baseEngine.core
{
    import baseEngine.utils.*;
    import com.gengine.debug.*;
    import com.gengine.resource.*;
    import com.gengine.resource.info.*;
    import flash.display.*;
    import flash.display3D.textures.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.utils.*;
    import frEngine.*;
    import frEngine.event.*;
    import frEngine.manager.*;

    public class Texture3D extends EventDispatcher
    {
        public var targetInfo:ImageInfo;
        public var canDispose:Boolean = true;
        public var texture:TextureBase;
        public var textureWidth:uint;
        public var textureHeight:uint;
        private var _data:Object;
        private var _request:Object;
        private var _optimizeForRenderToTexture:Boolean = false;
        public var loadFlag:uint = 0;
        public var filterMode:int = 1;
        public var mipMode:int = 0;
        public var typeMode:int = 0;
        public var bias:int = 0;
        public var options:int = 0;
        public var format:int;
        public var loadPriority:int = 3;
        private var _loadedAndUpload:Boolean = false;
        public static const FILTER_NEAREST:int = 0;
        public static const FILTER_LINEAR:int = 1;
        public static const TYPE_2D:int = 0;
        public static const TYPE_CUBE:int = 1;
        public static const MIP_NONE:int = 0;
        public static const MIP_NEAREST:int = 1;
        public static const MIP_LINEAR:int = 2;
        public static const allTexutre3DMap:Dictionary = new Dictionary(false);

        public function Texture3D(param1, param2:int, param3:int = 0, param4:int = 3)
        {
            this.mipMode = param2;
            this.format = param3;
            this.loadPriority = param4;
            if (param1)
            {
                this.request = param1;
            }
            return;
        }// end function

        public function set loadedAndUpload(param1:Boolean) : void
        {
            this._loadedAndUpload = param1;
            if (param1 && this.loadFlag == 2)
            {
                this.immediatelyUpload();
            }
            return;
        }// end function

        public function get loadedAndUpload() : Boolean
        {
            return this._loadedAndUpload || this.loadFlag == 2;
        }// end function

        public function reUpload() : void
        {
            if (this.texture)
            {
                Texture3DUtils.unloadTextureWithoutDeleteMapID(this._request, this.mipMode);
                this.texture = null;
                if (this.immediatelyUpload() == false)
                {
                    Log.debugMsg(LogType.other, this._request + " reupload error !");
                }
            }
            return;
        }// end function

        public function set request(param1) : void
        {
            var _loc_3:int = 0;
            var _loc_4:DisplayObject = null;
            var _loc_5:Rectangle = null;
            var _loc_6:Matrix = null;
            var _loc_7:uint = 0;
            var _loc_8:uint = 0;
            var _loc_9:uint = 0;
            if (param1 == this._request)
            {
                this.downloadWithoutDeleteMapID();
            }
            else
            {
                this.download();
            }
            this._request = param1;
            if (param1 is Array)
            {
                this.format = TextureFormat.FORMAT_CUBEMAP;
            }
            var _loc_2:* = getQualifiedSuperclassName(param1).toLowerCase().split("::").pop();
            if (_loc_2 == "object")
            {
                _loc_2 = getQualifiedClassName(param1).toLowerCase().split("::").pop();
            }
            if (_loc_2 == "bytearray" || _loc_2 == "bytearrayasset")
            {
                if (param1.length >= 3 && String.fromCharCode(param1[0], param1[1], param1[2]) == "ATF")
                {
                    this._data = this._request;
                    if (this._data[6] == 255)
                    {
                        this._data.position = 12;
                    }
                    else
                    {
                        this._data.position = 6;
                    }
                    _loc_7 = this._data.readUnsignedByte();
                    _loc_8 = _loc_7 >> 7;
                    _loc_9 = _loc_7 & 127;
                    if (_loc_9 <= 1)
                    {
                        this.format = TextureFormat.FORMAT_COMPRESSED_BGRA;
                    }
                    else if (_loc_9 <= 3)
                    {
                        this.format = TextureFormat.FORMAT_COMPRESSED;
                    }
                    else
                    {
                        this.format = TextureFormat.FORMAT_COMPRESSED_ALPHA;
                    }
                    this.textureWidth = Math.pow(2, this._data.readUnsignedByte());
                    this.textureHeight = Math.pow(2, this._data.readUnsignedByte());
                    this.loadFlag = 2;
                }
                else
                {
                    throw new Error("不符合texture3d类型");
                }
            }
            else if (this.format == TextureFormat.FORMAT_CUBEMAP)
            {
                switch(_loc_2)
                {
                    case "array":
                    {
                        this._data = [];
                        _loc_3 = 0;
                        while (_loc_3 < 6)
                        {
                            
                            this._data[_loc_3] = this._request[_loc_3] is BitmapData ? (this._request[_loc_3]) : (this._request[_loc_3].bitmapData);
                            _loc_3++;
                        }
                        this.textureWidth = this._data[0].width;
                        this.textureWidth = this._data[0].height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "bitmap":
                    {
                        this._data = Texture3DUtils.extractCubeMap(this._request.bitmapData);
                        this.textureWidth = this._data[0].width;
                        this.textureWidth = this._data[0].height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "bitmapdata":
                    {
                        this._data = Texture3DUtils.extractCubeMap(this._request);
                        this.textureWidth = this._data[0].width;
                        this.textureWidth = this._data[0].height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "point":
                    {
                        this._optimizeForRenderToTexture = true;
                        this._data = this._request;
                        this.textureWidth = this._request.x;
                        this.textureWidth = this._request.y;
                        this.loadFlag = 2;
                        break;
                    }
                    case "string":
                    {
                        break;
                    }
                    default:
                    {
                        throw new Error("不符合texture3d类型");
                        break;
                    }
                }
                this.typeMode = TYPE_CUBE;
            }
            else
            {
                switch(_loc_2)
                {
                    case "point":
                    {
                        this._optimizeForRenderToTexture = true;
                        this._data = this._request;
                        this.textureWidth = this._data.x;
                        this.textureWidth = this._data.y;
                        this.loadFlag = 2;
                        break;
                    }
                    case "bitmapdata":
                    {
                        this._data = this._request as BitmapData;
                        this.textureWidth = this._data.width;
                        this.textureWidth = this._data.height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "btmap":
                    {
                        this._data = this._request.bitmapData;
                        this.textureWidth = this._data.width;
                        this.textureWidth = this._data.height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "displayobject":
                    {
                        _loc_4 = this._request as DisplayObject;
                        _loc_5 = _loc_4.getBounds(_loc_4);
                        _loc_6 = new Matrix(1, 0, 0, 1, -_loc_5.x, -_loc_5.y);
                        this._data = new BitmapData(_loc_5.width || 1, _loc_5.height || 1, true, 0);
                        this._data.draw(this._request, _loc_6);
                        this.textureWidth = this._data.width;
                        this.textureWidth = this._data.height;
                        this.loadFlag = 2;
                        break;
                    }
                    case "string":
                    {
                        break;
                    }
                    default:
                    {
                        throw new Error("不符合texture3d类型");
                        break;
                    }
                }
            }
            if (this.loadFlag == 0)
            {
                this.load();
            }
            else if (this.loadFlag == 2 && this._loadedAndUpload)
            {
                this.immediatelyUpload();
            }
            return;
        }// end function

        public function setTexture(param1:TextureBase) : void
        {
            this.texture = param1;
            if (param1)
            {
                this.loadFlag = 2;
                allTexutre3DMap[this] = true;
            }
            else
            {
                this.loadFlag = 0;
                delete allTexutre3DMap[this];
            }
            FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.TEXTURE_CREATE);
            return;
        }// end function

        public function dispose() : void
        {
            Resource3dManager.instance.disposeTexture3dImp(this);
            return;
        }// end function

        public function disposeImp() : void
        {
            if (!this.canDispose)
            {
                return;
            }
            if (this._request is String || this.targetInfo)
            {
                this.downloadWithoutDeleteMapID();
            }
            else
            {
                this.download();
            }
            this.clearSourceData();
            this.loadFlag = 0;
            return;
        }// end function

        public function clearSourceData() : void
        {
            if (this._data && this._data is BitmapData)
            {
                this._data.dispose();
            }
            this._data = null;
            if (this.targetInfo && this.targetInfo.isLoaded)
            {
                this.targetInfo.dispose();
            }
            return;
        }// end function

        public function get data()
        {
            return this._data;
        }// end function

        public function download() : void
        {
            if (!this.canDispose)
            {
                return;
            }
            if (this._request is String)
            {
                LoaderManager.instance.removeResourceEvent(this._request, this.completeEvent);
            }
            if (this.texture)
            {
                Texture3DUtils.unloadTexture(this._request, this.mipMode);
                this.setTexture(null);
            }
            this.loadFlag = 0;
            return;
        }// end function

        private function downloadWithoutDeleteMapID() : void
        {
            if (!this.canDispose)
            {
                return;
            }
            if (this.texture)
            {
                Texture3DUtils.unloadTextureWithoutDeleteMapID(this._request, this.mipMode);
                this.setTexture(null);
            }
            this.loadFlag = 0;
            return;
        }// end function

        public function get request()
        {
            return this._request;
        }// end function

        public function get optimizeForRenderToTexture() : Boolean
        {
            return this._optimizeForRenderToTexture;
        }// end function

        public function set optimizeForRenderToTexture(param1:Boolean) : void
        {
            this._optimizeForRenderToTexture = param1;
            return;
        }// end function

        public function load() : void
        {
            if (this.loadFlag > 0)
            {
                return;
            }
            if (this._request != null && this._request is String)
            {
                this.loadFlag = 1;
                Resource3dManager.instance.checkTexture3d(this, true);
                LoaderManager.instance.load(this._request, this.completeEvent, this.loadPriority);
            }
            return;
        }// end function

        public function immediatelyUpload() : Boolean
        {
            var _texture:TextureBase;
            if (this.texture)
            {
                return true;
            }
            if (this.targetInfo && this.targetInfo.isDispose)
            {
                return false;
            }
            if (this.loadFlag == 2 && this._data)
            {
                if (this._data is TextureBase)
                {
                    this.setTexture(this._data);
                }
                else
                {
                    try
                    {
                        _texture = Texture3DUtils.createTexture(this._request, this._data, this.format, this.typeMode, this.mipMode, this._optimizeForRenderToTexture);
                    }
                    catch (e:Error)
                    {
                        Log.error("texture upload error:" + e.message);
                    }
                    if (_texture)
                    {
                        this.setTexture(_texture);
                    }
                }
                return this.texture != null;
            }
            else
            {
                return false;
            }
        }// end function

        private function completeEvent(param1:ImageInfo) : void
        {
            this.targetInfo = param1;
            this.loadFlag = 2;
            this.format = param1.format;
            this.textureWidth = param1.bmpWidth;
            this.textureWidth = param1.bmpHeight;
            if (this.format == TextureFormat.FORMAT_RGBA)
            {
                this._data = param1.bitmapData;
            }
            else if (this.format == TextureFormat.FORMAT_CUBEMAP)
            {
                this._data = Texture3DUtils.extractCubeMap(param1.bitmapData);
            }
            else if (this.format == TextureFormat.FORMAT_COMPRESSED || this.format == TextureFormat.FORMAT_COMPRESSED_ALPHA || this.format == TextureFormat.FORMAT_COMPRESSED_BGRA)
            {
                this._data = param1.ATFByteArray;
            }
            if (this._loadedAndUpload)
            {
                this.immediatelyUpload();
            }
            return;
        }// end function

        override public function toString() : String
        {
            return "[object Texture3D name:" + this._request + "]";
        }// end function

    }
}
